﻿using System;
using System.Linq;
using System.Threading.Tasks;
using Abp.Domain.Repositories;
using Abp.Notifications;
using Abp.Runtime.Session;
using DHJ.Cost.CostBooking.Dto;
using DHJ.Cost.Excel;
using DHJ.Cost.Excel.Cache;
using DHJ.Cost.Notifications;
using DHJ.Cost.Timing;

namespace DHJ.Cost.CostBooking
{
    public class CostBookingAppService : CostAppServiceBase, ICostBookingAppService
    {
        private readonly ICostBookingManager _costBookingManager;
        private readonly IExcelDataCache _excelDataCache;
        private readonly IRepository<ExcelData, Guid> _excelDataRepository;
        private readonly IRepository<ExcelItemData, Guid> _excelItemDataRepository;
        private readonly IAppNotifier _appNotifier;

        public CostBookingAppService(ICostBookingManager costBookingManager,
            IRepository<ExcelData, Guid> excelDataRepository, IExcelDataCache excelDataCache,
            IRepository<ExcelItemData, Guid> excelItemDataRepository, IAppNotifier appNotifier)
        {
            _costBookingManager = costBookingManager;
            _excelDataRepository = excelDataRepository;
            _excelDataCache = excelDataCache;
            _excelItemDataRepository = excelItemDataRepository;
            _appNotifier = appNotifier;
        }

        public async Task SetExcelBatchDataToCache(ExcelCostImportInput input)
        {
            try
            {
                var batch = new ExcelBatchData
                {
                    BatchNum = input.BatchNum,
                    Cells = input.Cells
                };

                await _excelDataCache.AddExcelBatch(input.Id, input.ExcelTitle, input.ExcelType,
                    new OccurrenceTime(input.Time.Year, input.Time.Month), batch);

                var item = await _excelDataCache.GetCacheItemOrNull(input.Id);

                if (input.TotalNum == item.Batches.Sum(e => e.Cells.Count))
                {
                    await HandleExcelByExcelType(item);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }

        private async Task HandleExcelByExcelType(ExcelDataCacheItem input)
        {
            try
            {
                var excelData = new ExcelData
                {
                    Type = input.ExcelType,
                    Time = input.Time,
                    Title = input.ExcelTitle
                };

                await _excelDataRepository.InsertAsync(excelData);

                foreach (var batch in input.Batches)
                {
                    var item = new ExcelItemData
                    {
                        ExcelDataId = excelData.Id,
                        ItemIndex = batch.BatchNum,
                        Cells = batch.Cells
                    };

                    await _excelItemDataRepository.InsertAsync(item);
                }

                await _costBookingManager.HandleExcelByExcelType(input.ExcelType, input.Time,
                    input.Batches.OrderBy(e => e.BatchNum).SelectMany(e => e.Cells).ToList());

                await _appNotifier.SendMessageAsync(AbpSession.ToUserIdentifier(), "成本导入成功", NotificationSeverity.Success);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }
    }
}